package edu.cmu.cs.task7.model;

import java.util.ArrayList;
import java.util.HashMap;

import javax.swing.JCheckBox;

import com.ebay.sdk.ApiContext;
import com.ebay.sdk.ApiException;
import com.ebay.sdk.SdkException;
import com.ebay.sdk.helper.ServiceControlManager;
import com.ebay.sdk.helper.ShippingServiceHelper;
import com.ebay.sdk.helper.ShippingServiceSelector;
import com.ebay.sdk.helper.ui.ControlBuilder;
import com.ebay.sdk.helper.ui.ControlTagItem;
import com.ebay.sdk.util.eBayUtil;
import com.ebay.soap.eBLBaseComponents.AmountType;
import com.ebay.soap.eBLBaseComponents.BestOfferDetailsType;
import com.ebay.soap.eBLBaseComponents.BuyerPaymentMethodCodeType;
import com.ebay.soap.eBLBaseComponents.CategoryType;
import com.ebay.soap.eBLBaseComponents.CountryCodeType;
import com.ebay.soap.eBLBaseComponents.CurrencyCodeType;
import com.ebay.soap.eBLBaseComponents.DetailLevelCodeType;
import com.ebay.soap.eBLBaseComponents.EndReasonCodeType;
import com.ebay.soap.eBLBaseComponents.FeeType;
import com.ebay.soap.eBLBaseComponents.FeesType;
import com.ebay.soap.eBLBaseComponents.ItemType;
import com.ebay.soap.eBLBaseComponents.ListingDurationCodeType;
import com.ebay.soap.eBLBaseComponents.ListingEnhancementsCodeType;
import com.ebay.soap.eBLBaseComponents.ListingTypeCodeType;
import com.ebay.soap.eBLBaseComponents.ReturnPolicyType;
import com.ebay.soap.eBLBaseComponents.ShippingDetailsType;
import com.ebay.soap.eBLBaseComponents.ShippingServiceCodeType;
import com.ebay.soap.eBLBaseComponents.ShippingServiceOptionsType;
import com.ebay.soap.eBLBaseComponents.ShippingTypeCodeType;
import com.ebay.soap.eBLBaseComponents.SiteCodeType;
import com.ebay.soap.eBLBaseComponents.VATDetailsType;

public class AddItemModel extends Model {
	private ApiContext apiContext=new ApiContext();
	private SiteCodeType siteId;
	private HashMap params;
		
	ControlTagItem[] ctrlPaymentServices = new ControlTagItem[] {};
	ArrayList shippingServiceOptions = new ArrayList();
	ArrayList intlShippingServiceOptions = new ArrayList();
    
	public AddItemModel(ApiContext apiContext, HashMap params) throws Exception{
		 this.params=params;
		 this.apiContext=apiContext;
		 this.siteId = SiteCodeType.US;  //The default site
		 //customInit(); //This involves a lot of initialization due to change of site and listing type; 
		                 //But for simplicity, we will truncate this and it's corresponding options
    }
	
	//The params is a HashMap holding all the variables possiblly about this item
	public String [] AddItem() throws SdkException, Exception{
	    try{
	      //this.apiContext.setSite(this.siteId);
		  //this.siteId=(SiteCodeType) params.get("siteid"); //If user selected another site
		  CurrencyCodeType currency = CurrencyCodeType.USD;  //The default
//	      if (this.siteId == SiteCodeType.UK) {
//	        currency = CurrencyCodeType.GBP;
//	      }
//	      else if (this.siteId == SiteCodeType.GERMANY){
//	        currency = CurrencyCodeType.EUR;
//	      }
//	      else if (this.siteId == SiteCodeType.CANADA) {
//	        currency = CurrencyCodeType.CAD;
//	      }
	      
	
	      com.ebay.sdk.call.AddItemCall api = new com.ebay.sdk.call.AddItemCall(this.apiContext);
	      // Let the call object to automatically generate UUID for my item.
	      api.setAutoSetItemUUID(false);
	      api.setSite(this.siteId);
	
	      // Set detail level to retrieve item description.
	      api.addDetailLevel(DetailLevelCodeType.ITEM_RETURN_DESCRIPTION);
	
	      ItemType item = getItemFromForm();
	      
	      //fill in mandatory fields
	      //handling time
	      item.setDispatchTimeMax(Integer.valueOf(1));
	      //return policy
	      ReturnPolicyType returnPolicy = new ReturnPolicyType();
	      returnPolicy.setReturnsAcceptedOption("ReturnsAccepted");
	      item.setReturnPolicy(returnPolicy);
	
	      item.setCurrency(currency);
	
	      
	      //api.setPictureFiles(this.getPicturePathList());  //Handle this later
	      String[] picturePathList=(String[])params.get("picturepaths");
	      api.setPictureFiles(picturePathList);
	      
	      if(params.get("listingtype").equals("CHINESE")){
	    	  item.setListingType(ListingTypeCodeType.CHINESE);
	      }else if(params.get("listingtype").equals("LIVE")){
	    	  item.setListingType(ListingTypeCodeType.LIVE);
	      }else if(params.get("listingtype").equals("AD_TYPE")){
	    	  item.setListingType(ListingTypeCodeType.AD_TYPE);
	      }else if(params.get("listingtype").equals("PERSONAL_OFFER")){
	    	  item.setListingType(ListingTypeCodeType.PERSONAL_OFFER);
	      }
	      
	      //new ControlTagItem("New", new Integer(1000)),
	      //new ControlTagItem("Used", new Integer(3000)),
	      //item.setConditionID((Integer)((ControlTagItem)this.cbxCondition.getSelectedItem()).Tag);
	      //The above three lines are just for reference
	      Integer conditionid=Integer.parseInt((String)params.get("conditionid"));
	      item.setConditionID(conditionid);
	         
	      api.setItem(item);
	      FeesType fees = api.addItem();
		  //return the item id and listing fee
		  String [] result= new String[2];
		  result[0]=item.getItemID();
		  FeeType ft = eBayUtil.findFeeByName(fees.getFee(), "ListingFee");
	      result[1] = new Double(ft.getFee().getValue()).toString();
	      return result;
	    }catch(ApiException e){
	      String [] result= new String[2];
	      result[0]="error";
	      result[1]=e.toString();
	      return result;
	    }
	}
	
	
	private ItemType getItemFromForm() throws Exception
	  {
	    String s;

	    ItemType item = new ItemType();

	    item.setTitle((String)params.get("title"));

	    String subTitle = "sub title"; //Useless code from the sample?
	    if (subTitle.length() > 0) {
	      item.setSubTitle(subTitle);
	    }

	    item.setDescription((String)params.get("description"));

	    ControlTagItem ct = null; 
	    String duration=(String)params.get("duration");
	    if(duration.equalsIgnoreCase("1 day")){
            ct = new ControlTagItem("1 day", ListingDurationCodeType.DAYS_1);
	     }else if(duration.equalsIgnoreCase("3 days")){
	    	 ct= new ControlTagItem("3 days", ListingDurationCodeType.DAYS_3);
	     }else if(duration.equalsIgnoreCase("5 days")){
	    	 ct= new ControlTagItem("5 days", ListingDurationCodeType.DAYS_5); 
	     }else if(duration.equalsIgnoreCase("7 days")){
	    	 ct= new ControlTagItem("7 days", ListingDurationCodeType.DAYS_7);
	     }else if(duration.equalsIgnoreCase("GTC")){ //The default
	    	 ct = new ControlTagItem("GTC", ListingDurationCodeType.GTC);
	     }

	    if (null != ct.Tag)
	    	item.setListingDuration(((ListingDurationCodeType)ct.Tag).value());

	    //Some default values are set here; 
	    //if user modifies these default value, they are reflected in AddItem(...) function
	    item.setRegionID("0");
	    item.setLocation("San Jose, CA");
	    item.setCurrency(CurrencyCodeType.USD);
	    item.setQuantity(new Integer((String)params.get("quantity")));
	    item.setCountry(CountryCodeType.US);

	    CategoryType cat = new CategoryType();
	    cat.setCategoryID((String)params.get("categoryid"));
	    item.setPrimaryCategory(cat);

	    s = (String)params.get("startprice");
	    if( s.length() == 0 )
	      throw new Exception("Please enter start price.");
	    AmountType at = new AmountType();
	    at.setValue(Double.parseDouble(s));
	    item.setStartPrice(at);
        
	    String rp=(String)params.get("reserveprice");
	    if( rp.length() > 0 )
	    {
	    	at = new AmountType();
	    	at.setValue(Double.parseDouble(rp));
	        item.setReservePrice(at);
	    }
        
	    String bp=(String)params.get("binprice");
	    if( bp.length() > 0 ) {
	    	at = new AmountType();
	    	at.setValue(Double.parseDouble(bp));
	        item.setBuyItNowPrice(at);
	    }

	    ServiceControlManager manager = ServiceControlManager.getInstance();
	    BuyerPaymentMethodCodeType bpm = null ;
	    String[] paymethods=(String [])params.get("ckbpaymethods");
	    ArrayList<BuyerPaymentMethodCodeType> pl=new ArrayList<BuyerPaymentMethodCodeType>() ;
	    for(int i=0;i<paymethods.length;i++){//Only electronic payment methods allowed now
	    	//if(paymethods[i].equals("PAYMENT_SEE_DESCRIPTION")){  
	    		//pl.add(bpm.PAYMENT_SEE_DESCRIPTION);
	    	if(paymethods[i].equals("PAY_PAL")){
	    		pl.add(bpm.PAY_PAL);
	    	}else if(paymethods[i].equals("DISCOVER")){
	    		pl.add(bpm.DISCOVER);
	    	}else if(paymethods[i].equals("AM_EX")){
	    		pl.add(bpm.AM_EX);
	    	}else if(paymethods[i].equals("VISA_MC")){
	    		pl.add(bpm.VISA_MC);
	    	}
	    	//}else if(paymethods[i].equals("PERSONAL_CHECK")){
	    		//pl.add(bpm.PERSONAL_CHECK);
	    	//}else if(paymethods[i].equals("MOCC")){  //Money order or cashier's check
	    		//pl.add(bpm.MOCC);
	    	//}	    	
	    }
	    
	    BuyerPaymentMethodCodeType[] arrPaymentMethods=new BuyerPaymentMethodCodeType[pl.size()] ;
	    for(int i=0;i<pl.size();i++){
	    	arrPaymentMethods[i]=pl.get(i); 
	    }
	    
	    
	    if (arrPaymentMethods != null) {
	      item.setPaymentMethods(arrPaymentMethods);
	    }

	    
	    handleShippingService();
	    //handleInternationalShippingService();  //similar with domestic shipping; but don't handle it for now.
	    
	    ShippingDetailsType shippingDetails =
	        manager.processUserShippingDetails(this.shippingServiceOptions, this.intlShippingServiceOptions);
	    if (shippingDetails != null) {
	      item.setShippingDetails(shippingDetails);
	    }

	    String[] list=(String [])params.get("ckbShipToLocations");
	    //ArrayList list = manager.getSelectedCheckBoxList(this.ckbShipToLocations);
	     
	     if (list.length > 0) {
	      item.setShipToLocations(list);
	     }

	    String payPalEmail = ((String)params.get("paypalemail")).trim();
	    if (payPalEmail.length() > 0) {
	      item.setPayPalEmailAddress(payPalEmail);
	    }

	    String vatPercent = ((String)params.get("vatpercent")).trim();   //VAT: value added tax
	    if (vatPercent.length() > 0) {
	      VATDetailsType vatDetails = new VATDetailsType();
	      vatDetails.setVATPercent(new Float(vatPercent));
	      item.setVATDetails(vatDetails);
	    }

//	    item.setAutoPay((Boolean)params.get("autopay"));
	    item.setAutoPay(false);  //since enable it will require paypal premium, just disable it
	    //boolean borderChecked = this.ckbBorder.isSelected();  //Border attribute is no longer available
	    boolean boldTitleChecked = (Boolean)params.get("boldtitle");
	    int cnt = 0;
//	    if (borderChecked) {
//	      cnt++;
//	    }
	    if (boldTitleChecked) {
	      cnt++;
	    }

	    if (cnt > 0) {
	      ListingEnhancementsCodeType enhancements[] = new ListingEnhancementsCodeType [cnt];
	      cnt = 0;
//	      if (borderChecked) {
//	        enhancements[cnt++] = ListingEnhancementsCodeType.BORDER;
//	      }
	      if (boldTitleChecked) {
	        enhancements[cnt] = ListingEnhancementsCodeType.BOLD_TITLE;
	      }
	      item.setListingEnhancement(enhancements);
	    }

	    String lotSize = ((String)params.get("lotsize")).trim();  //The size of clothes or shoes etc
	    if (lotSize.length() > 0) {
	      item.setLotSize(new Integer(lotSize));
	    }

//	    if( this.cbxBestOffer.isSelected() )    //No best offer for US site
//	    {
//	      BestOfferDetailsType bo = new BestOfferDetailsType();
//	      bo.setBestOfferEnabled(new Boolean(true));
//	      item.setBestOfferDetails(bo);
//	    }

	    return item;
	  }
	
	
	  public void handleShippingService(){  //set the result in class variable
		    //This piece form DialogAddItem
		    ServiceControlManager manager = ServiceControlManager.getInstance();
		    ControlTagItem[] ctrlServices = manager.createShippingServiceControl(this.siteId, ShippingServiceHelper.FLAT_SHIPPING_METHODS, false);    
		    ShippingServiceSelector selector = new ShippingServiceSelector(ShippingTypeCodeType.FLAT, null, ctrlServices);
		    
		    //This piece is from DialogEditShippingService
		    ShippingServiceOptionsType sso = new ShippingServiceOptionsType();
		    Integer idx = Integer.parseInt((String)params.get("shippingserviceindex"));
		    sso.setShippingService(((ShippingServiceCodeType)
		                            selector.getCtrlShippingServices()[
		                            idx].Tag).value());
		    if (selector.getShippingType() ==
		        ShippingTypeCodeType.FLAT) {
		      String cost = (String)params.get("shippingservicecost");
		      if (cost.length() > 0) {
		    	  AmountType at2 = new AmountType();
		    	  at2.setValue(Double.parseDouble(cost));
		          sso.setShippingServiceCost(at2);
		      }
		      cost = (String)params.get("additionalshippingservicecost");
		      if (cost.length() > 0) {
		    	  AmountType at3 = new AmountType();
		    	  at3.setValue(Double.parseDouble(cost));
		          sso.setShippingServiceAdditionalCost(at3);
		      }
		    }
		    selector.setSelectedShippingServiceOption(sso);
		    
		    
		    //Now from DialogAddItem again
		    sso = selector.getSelectedShippingServiceOption();
		    if (sso != null) {
		      this.shippingServiceOptions.add(selector);
		      sso.setShippingServicePriority(new Integer(this.shippingServiceOptions.size()));
		      //updateShippingServiceSelections();  Not sure whether this line is useful
		    }
		    //Now the above section selects the type of shipping method selected  
	  }
      
	  public void handleInternationalShippingService(){  //Not handled yet
		  
	  }
}
